home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS12.ADF / C / vsprite / mygeltools.c < prev    next >
C/C++ Source or Header  |  1986-08-05  |  15KB  |  427 lines

  1.  
  2.  
  3. #include <exec/types.h>
  4. #include <exec/exec.h>
  5. #include <graphics/gfxmacros.h>
  6. #include <graphics/gels.h>
  7. #include <graphics/collide.h>
  8. #include <intuition/intuition.h>
  9.  
  10.  
  11. /*******************************************************************************
  12.  * This file is a collection of tools which are used with the vsprite and
  13.  * bob software.  It contains the following:
  14.  *
  15.  * ReadyGels( *gelsinfo, *rastport );
  16.  * PurgeGels( *gelsinfo );
  17.  *
  18.  * struct VSprite *MakeVSprite(lineheight,*image,*colorset,x,y,
  19.  *    wordwidth,imagedepth,flags);       
  20.  * DeleteVSprite( &VSprite );
  21.  *
  22.  * struct Bob *MakeBob(bitwidth,lineheight,imagedepth,*image,
  23.  *       planePick,planeOnOff,x,y)
  24.  * DeleteBob( &Bob );
  25.  *
  26.  * ReadyGels sets up the defaults of the gel system by initializing the
  27.  * GelsInfo structure you provide.  First it allocates room for and
  28.  * links in lastcolor and nextline. It then uses information in your
  29.  * RastPort structure to establish boundary collision defaults at
  30.  * the outer edges of the raster.  It then links together the GelsInfo
  31.  * and the RastPort which you provide. Next it allocates space for two
  32.  * dummy virtual sprite structures, calls InitGels and SetCollision.
  33.  ! You must already have run LoadView before ReadyGels is called.
  34.  *
  35.  * PurgeGels deallocates all memory which ReadyGels and NewGelList have
  36.  * allocated.  The system will crash if you have not used these
  37.  * routines to allocate the space (you cant deallocate something
  38.  * which you havent allocated in the first place).
  39.  *
  40.  * MakeVSprite allocates enough space for and inits a normal vsprite.
  41.  * DeleteVSprite deallocates the memory it used.
  42.  *
  43.  * MakeBob initializes a standard bob and allocates as much memory as is needed
  44.  * for a normal bob and its vsprite structure, links them together.
  45.  * To find the associated vsprite, look at the back-pointer (see the
  46.  * routine doc itself).
  47.  * DeleteBob deallocates the memory it used.
  48.  *
  49.  * Written by Rob Peck, with thanks to Barry Whitebrook and David Lucas.
  50.  *
  51.  ******************************************************************************/
  52.  
  53. void border_dummy()
  54.    return; 
  55. }
  56.  
  57. /* Caller passes a pointer to his GelsInfo structure which he wants to init, 
  58.  * along with a pointer to his IVPArgs.  Default init places the topmost
  59.  * bottommost etc at the outermost boundaries of callers rastport parameters.
  60.  */
  61.  
  62. extern struct RastPort *myRast;
  63.  
  64. struct VSprite *SpriteHead = NULL;
  65. struct VSprite *SpriteTail = NULL;
  66.  
  67. /*******************************************************************************
  68.  * This routine cannot be run until the first LoadView(&view) has been
  69.  * executed.  InitGels works with an already active View, so LoadView
  70.  * must have been run first.
  71.  */
  72.  
  73. ReadyGels(g, r)
  74. struct RastPort *r;
  75. struct GelsInfo *g;
  76. {
  77. /* Allocate head and tail of list. */
  78.  
  79.    if ((SpriteHead = (struct VSprite *)AllocMem(sizeof
  80.           (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  81. #ifdef DEBUG
  82.       kprintf("ReadyGels: No memory for sprite head.\n");
  83. #endif
  84.       return(-1);
  85.    }
  86.  
  87.    if ((SpriteTail = (struct VSprite *)AllocMem(sizeof
  88.           (struct VSprite), MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  89. #ifdef DEBUG
  90.       kprintf("ReadyGels: No memory for sprite tail.\n");
  91. #endif
  92.       return(-1);
  93.    }
  94.  
  95.        /* By setting all bits here, it means that there are NO
  96.    * reserved sprites.  The system can freely use all of the 
  97.    * hardware sprites for its own purposes.  The caller will not be
  98.    * trying to independently use any hardware sprites!
  99.    */
  100.  
  101.    g->sprRsrvd = -1;
  102.  
  103.        /* The nextline array is used to hold system information about
  104.    * "at which line number on the screen is this hardware sprite
  105.    * again going to become available to be given a new vsprite to
  106.    * display".
  107.    */
  108.  
  109.    if ((g->nextLine = (WORD *)AllocMem(sizeof(WORD) * 8,
  110. /**/         MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
  111. #ifdef DEBUG
  112.       kprintf("ReadyGels: No memory for nextline.\n");
  113. #endif
  114.       return(-1);
  115.    }
  116.  
  117.        /* In the lastcolor pointer array, the system will store
  118.    * a pointer to the color definitions most recently used
  119.    * by the system. .... as a reminder, virtual sprites can
  120.    * be assigned to any of the real hardware sprites which
  121.    * may be available at the time.  The vsprite colors will
  122.    * be written into the hardware sprite register set for
  123.    * the hardware sprite to which that vsprite is assigned.
  124.    * This pointer array contains one pointer to the last
  125.    * set of three colors (from the vsprite structure *sprColors)
  126.    * for each hardware sprite.  
  127.    *
  128.    * As the system is scanning to determine which hardware 
  129.    * sprite should next be used to represent a vsprite, it
  130.    * checks the contents of this array.  If a hardware sprite
  131.    * is available and already has been assigned this set of
  132.    * colors, no color assignment is needed, and therefore
  133.    * no color change instructions will be generated for the
  134.    * copper list.
  135.    *
  136.    * If all vsprites use a different set of sprColors, (pointers
  137.    * to sprColors are different for all vsprites), then there
  138.    * is a limit of 4 vsprites on a horizontal line.  If, on
  139.    * the other hand, you define, lets say 8 vsprites, with
  140.    * 1 and 2 having the same sprColors, 3 and 4 the same as
  141.    * each other, 5 and 6 the same as each other, and 7 and 8
  142.    * also having the same vsprite colors, then you will be
  143.    * able to have all 8 vsprites on the same horizontal line.
  144.    *
  145.    * In this case, you will be able to put all 8 vsprites on
  146.    * the same horizontal line.  The reason this helps is that
  147.    * the system hardware shares the color registers between pairs
  148.    * of hardware sprites.  The system thus has enough resources
  149.    * to assign all vsprites to hardware sprites in that there
  150.    * are 4 color-sets for 8 vsprites, exactly matching the 
  151.    * hardware maximum capabilities.
  152.    *
  153.    * Note that lastcolor will not be used for bobs. Just sprites.
  154.    */
  155.  
  156.    if ((g->lastColor = (WORD **)AllocMem(sizeof(LONG) * 8,
  157.          MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
  158. #ifdef DEBUG
  159.       kprintf("ReadyGels: No memory for lastcolor.\n");
  160. #endif
  161.       return(-1);
  162.    }
  163.  
  164.        /* This is a table of pointers to the routines which should
  165.    * be performed when DoCollision senses a collision.  This
  166.    * declaration may not be necessary for a basic vsprite with
  167.    * no collision detection implemented, but then it makes for
  168.    * a complete example.
  169.    */
  170.  
  171.    if ((g->collHandler = (struct collTable *)AllocMem(sizeof(struct
  172. /**/         collTable), MEMF_PUBLIC | MEMF_CLEAR)) == NULL) {
  173. #ifdef DEBUG
  174.       kprintf("ReadyGels: No memory for collHandler.\n");
  175. #endif
  176.       return(-1);
  177.    }
  178.  
  179.        /* When any part of the object touches or passes across
  180.    * this boundary, it will cause the boundary collision
  181.    * routine to be called.  This is at smash[0] in the
  182.    * collision handler table and is called only if
  183.    * DoCollision is called.
  184.    */
  185.  
  186.    g->leftmost = 0;
  187.    g->rightmost = r->BitMap->BytesPerRow * 8 - 1;
  188.    g->topmost = 0;
  189.    g->bottommost = r->BitMap->Rows - 1;
  190.  
  191.    r->GelsInfo = g;   /* link together the two structures */
  192.  
  193.    InitGels(SpriteHead, SpriteTail, g );   
  194.  
  195.        /* Pointers initialized to the dummy sprites which will be
  196.    * used by the system to keep track of the animation system.
  197.    */
  198.    SetCollision(0, border_dummy, g);
  199.    WaitTOF();
  200.    return(0);
  201. }
  202.  
  203. /*******************************************************************************
  204.  * Use this to get rid of the gels stuff when it is not needed any more.
  205.  * You must have allocated the gels info stuff (use the ReadyGels routine).
  206.  */
  207.  
  208. PurgeGels(g)
  209. struct GelsInfo *g;
  210. {
  211.    if (g->collHandler != NULL)
  212.       FreeMem(g->collHandler, sizeof(struct collTable));
  213.    if (g->lastColor != NULL)
  214.       FreeMem(g->lastColor, sizeof(LONG) * 8);
  215.    if (g->nextLine != NULL)
  216.       FreeMem(g->nextLine,  sizeof(WORD) * 8);
  217.    if (g->gelHead != NULL)
  218.       FreeMem(g->gelHead, sizeof(struct VSprite));
  219.    if (g->gelTail != NULL)
  220.       FreeMem(g->gelTail, sizeof(struct VSprite));
  221. }
  222.  
  223.  
  224. /******************************************************************************
  225.  * Because MakeVSprite is called by MakeBob, MakeVSprite only creates the
  226.  * VSprite,it doesn't add it to the system list. The calling routine must
  227.  * do an AddVSprite after it is created.
  228.  */
  229.  
  230. struct VSprite *MakeVSprite(lineheight, image, colorset, x, y,
  231.             wordwidth, imagedepth, flags)
  232. SHORT lineheight;   /* how tall is this vsprite? */
  233. WORD *image;      /* where is the vsprite image data, should be
  234.             twice as many words as the value of lineheight */
  235. WORD *colorset;      /* where is the set of three words which describes
  236.             the colors that this vsprite can take on? */
  237. SHORT x, y;      /* what is its initial onscreen position? */
  238. SHORT wordwidth, imagedepth, flags;
  239. {
  240.    struct VSprite *v;   /* make a pointer to the vsprite structure which
  241.                this routine dynamically allocates */
  242.  
  243.    if ((v = (struct VSprite *)AllocMem(sizeof(struct VSprite),
  244.          MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  245. #ifdef DEBUG
  246.       printf("MakeVSprite: Couldn't allocate VSprite.\n");
  247. #endif
  248.       return(0);
  249.    }
  250.  
  251.    v->Flags = flags;   /* is this a vsprite, not a bob? */
  252.  
  253.    v->Y = y;      /* Establish initial position relative to */
  254.    v->X = x;      /* the Display coordinates. */
  255.  
  256.    v->Height = lineheight;   /* user says how high it is */
  257.    v->Width = wordwidth;   /* a vsprite is always 1 word (16 bits) wide */
  258.  
  259.        /* There are two kinds of depth... the depth of the image itself, and the
  260.    * depth of the playfield into which it will be drawn. The image depth
  261.    * says how much data space will be needed to store an image if it's
  262.    * dynamically allocated. The playfield depth establishes how much space
  263.    * will be needed to save and restore the background when a bob is drawn.
  264.    * A vsprite is always 2 planes deep, but if it's being used to make a
  265.         * bob, it may be deeper...
  266.    */
  267.  
  268.    v->Depth = imagedepth;
  269.  
  270.        /* Assume that user at least has a default boundary collision
  271.    * routine.... bit 1 of this mask is reserved for boundary collision
  272.    * detect during DoCollision(). The only collisions reported will be
  273.    * with the borders. The caller can change all this later.
  274.    */
  275.  
  276.    v->MeMask = 1;
  277.    v->HitMask = 1;
  278.  
  279.    v->ImageData = image;   /* Caller says where to find the image. */
  280.  
  281.        /* Show system where to find a mask which is a squished down version
  282.    * of the vsprite (allows for fast horizontal border collision detect).
  283.    */
  284.  
  285.    if ((v->BorderLine = (WORD *)AllocMem((sizeof(WORD)*wordwidth),
  286. /**/         MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  287. #ifdef DEBUG
  288.       kprintf("MakeVSprite: Couldn't allocate BorderLine.\n");
  289. #endif
  290.       return(0);
  291.    }
  292.  
  293.        /* Show system where to find the mask which contains a 1 bit for any
  294.    * position in the object in any plane where there is a 1 bit (all planes
  295.    * OR'ed together).
  296.    */
  297.  
  298.    if ((v->CollMask = (WORD *)AllocMem(sizeof(WORD)*lineheight*wordwidth,
  299.          MEMF_CHIP | MEMF_CLEAR)) == 0) {
  300. #ifdef DEBUG
  301.       kprintf("MakeVSprite: Couldn't allocate CollMask.\n");
  302. #endif
  303.       return(0);
  304.    }
  305.  
  306.    /* This isn't used for a Bob, just a VSprite. It's where the
  307.     * Caller says where to find the VSprites colors.
  308.     */
  309.    v->SprColors = colorset;
  310.  
  311.    /* These aren't used for a VSprite, and MakeBob'll do set up for Bob. */
  312.    v->PlanePick = 0x00;
  313.    v->PlaneOnOff = 0x00;
  314.  
  315.    InitMasks(v);   /* create the collMask and borderLine */   
  316.    return(v);
  317. }
  318.  
  319. struct Bob *MakeBob(bitwidth,lineheight,imagedepth,image,
  320.       planePick,planeOnOff, x,y, flags)
  321. SHORT bitwidth,lineheight,imagedepth,planePick,planeOnOff,x,y,flags;
  322. WORD *image;
  323. {
  324.    struct Bob *b;
  325.    struct VSprite *v;
  326.    SHORT wordwidth;
  327.    wordwidth = (bitwidth+15)/16;
  328.  
  329.        /* Create a vsprite for this bob, it will need to be deallocated
  330.    * later (freed) when this bob gets deleted.
  331.    * Note: No color set for bobs.
  332.         */
  333.    if ((v = MakeVSprite(lineheight, image, NULL, x, y, wordwidth,
  334.          imagedepth, flags)) == 0) {
  335. #ifdef DEBUG
  336.       kprintf("MakeBob: MakeVSprite failed.\n");
  337. #endif
  338.       return(0);
  339.    }
  340.  
  341.    /* Caller selects which bit planes into which the image is drawn. */
  342.    v->PlanePick = planePick;
  343.  
  344.    /* What happens to the bit planes into which the image is not drawn. */
  345.    v->PlaneOnOff = planeOnOff;
  346.  
  347.    if ((b = (struct Bob *)AllocMem(sizeof(struct Bob),
  348.          MEMF_PUBLIC | MEMF_CLEAR)) == 0) {
  349. #ifdef DEBUG
  350.       kprintf("MakeBob: Couldn't allocate bob.\n");
  351. #endif
  352.       return(0);
  353.    }
  354.  
  355.    v->VSBob = b;   /* Link together the bob and its vsprite structures */
  356.  
  357.    b->Flags = 0; /* Not part of an animation (BOBISCOMP) and don't keep the
  358.          image present after bob is removed (SAVEBOB) */ 
  359.  
  360.        /* Tell where to save background. Must have enough space for as many
  361.    * bitplanes deep as the display into which everything is being drawn.
  362.    */
  363.  
  364.    if ((b->SaveBuffer = (WORD *)AllocMem(sizeof(SHORT) * wordwidth
  365. /**/       * lineheight * imagedepth, MEMF_CHIP | MEMF_CLEAR)) == 0) {
  366. #ifdef DEBUG
  367.       kprintf("MakeBob: Couldn't allocate save buffer.\n");
  368. #endif
  369.       return(0);
  370.    }
  371.  
  372.    b->ImageShadow = v->CollMask;
  373.  
  374.        /* Interbob priorities are set such that the earliest defined bobs have
  375.    * the lowest priority, last bob defined is on top.
  376.    */
  377.  
  378.    b->Before = NULL;   /* Let the caller worry about priority later. */
  379.    b->After = NULL;
  380.  
  381.    b->BobVSprite = v;
  382.  
  383.        /* InitMasks does not preset the imageShadow ... user may elect to use
  384.    * the collMask or to create his own version of a shadow, although it
  385.    * is usually the same.
  386.    */
  387.  
  388.    b->BobComp = NULL;   /* this is not part of an animation */
  389.    b->DBuffer = NULL;   /* this is not double buffered */
  390.  
  391.        /* Return a pointer to this newly created bob for additional caller
  392.    * interaction or for AddBob(b);
  393.    */
  394.    return(b);
  395. }
  396.  
  397. /* Deallocate memory which has been allocated by the routine MakeGel. */
  398. /* assumes images and imageshadow deallocated elsewhere */
  399. DeleteGel(v)
  400. struct VSprite *v;
  401. {
  402.    if (v != NULL) {
  403.       if (v->VSBob != NULL) {
  404.          if (v->VSBob->SaveBuffer != NULL) {
  405.             FreeMem(v->VSBob->SaveBuffer, sizeof(SHORT) * v->Width
  406.                   * v->Height * v->Depth);
  407.          }
  408.          if (v->VSBob->DBuffer != NULL) {
  409.             if (v->VSBob->DBuffer->BufBuffer != 0) {
  410.                FreeMem(v->VSBob->DBuffer->BufBuffer,
  411.                      sizeof(SHORT) * v->Width * v->Height * v->Depth);
  412.             }
  413.             FreeMem(v->VSBob->DBuffer, sizeof(struct DBufPacket));
  414.          }
  415.          FreeMem( v->VSBob, sizeof(struct Bob));
  416.       }
  417.       if (v->CollMask != NULL) {
  418.          FreeMem(v->CollMask, sizeof(WORD) * v->Height * v->Width);
  419.       }
  420.       if (v->BorderLine != NULL) {
  421.          FreeMem(v->BorderLine, sizeof(WORD) * v->Width);
  422.       }
  423.       FreeMem(v, sizeof(struct VSprite));
  424.    }
  425. }
  426.